package com.pt25.study.example.interfaces.facade.test;


import cn.hutool.json.JSONObject;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import com.pt25.base.dep.es.EsService;
import com.pt25.base.dep.es.Es7Service;
import com.pt25.base.dep.es.ddo.Mapping;
import com.pt25.base.dep.es.ddo.MappingProperty;
import com.pt25.base.model.common.constants.EsConstant;
import com.pt25.base.res.ResBody;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jnr.ffi.annotations.In;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Slf4j
@Tag(name = "es test api")
@RefreshScope
@RestController
@RequestMapping("/test-api/example")
public class EsTestController {
    private final static String TEST_ES = "/test-es";
    private final static String TEST_ES8 = "/test-es8";
    private final static String TEST_ES7 = "/test-es7";
    private final static String TEST_MIX_QUERY = "/test-mix-query";
    private final static String TEST_CREATE_ES_INDEX = "/test-create-es-index";
    @Resource
    private Es7Service es7Service;

    @Resource
    private EsService esService;


    @Operation(summary = "测试es相关操作")
    @GetMapping(TEST_ES)
    public ResBody testES() throws Exception {
        String cluster = EsConstant.ES1; // or "cluster2"
        String index = "test_index";
        String id = "1";

//        // 索引文档
//        Map<String, Object> document = new HashMap<>();
//        document.put("field", "value");
//        esService.indexDocument(cluster, index, id, document);

        // 获取文档
        GetResponse response = es7Service.getDocument(cluster, index, id);
        System.out.println(response.getSourceAsString());
//
//        // 更新文档
//        Map<String, Object> update = new HashMap<>();
//        update.put("field", "new_value");
//        esService.updateDocument(cluster, index, id, update);
//
//        // 删除文档
//        esService.deleteDocument(cluster, index, id);
//
//        // 搜索文档
//        esService.searchDocuments(cluster, index, "field", "value");
//
//        // 批量操作
//        BulkRequest bulkRequest = new BulkRequest();
//        bulkRequest.add(new IndexRequest(index).id("2").source(document, XContentType.JSON));
//        bulkRequest.add(new IndexRequest(index).id("3").source(document, XContentType.JSON));
//        esService.bulkOperations(cluster, bulkRequest);
//
//        // 分页查询
//        esService.searchDocumentsWithPagination(cluster, index, QueryBuilders.matchQuery("field", "value"), 1, 10);

        return ResBody.builder().build().ok();
    }

    @Operation(summary = "测试es创建索引")
    @GetMapping(TEST_CREATE_ES_INDEX)
    public ResBody testCreateESIndex() throws Exception {
        String cluster = EsConstant.ES1; // or "cluster2"

        MappingProperty mappingProperty = MappingProperty.builder().build();
        mappingProperty.setType("text");
        mappingProperty.setName("name");
        mappingProperty.setIndex(true);

        Mapping mapping = Mapping.builder().index("test_index1").shards(3).replicas(1).properties(new ArrayList<>()).build();
        mapping.getProperties().add(mappingProperty);

        Boolean testIndex1 = es7Service.existIndex(cluster, "test_index1");
        System.out.println(testIndex1);

        return ResBody.builder().build().ok();
    }

    @Operation(summary = "测试es8")
    @GetMapping(TEST_ES8)
    public ResBody testEs8() throws Exception {
        String indexName = "test_es7_index";
        if (esService.existIndex(EsConstant.ES7, indexName)) {
            esService.deleteIndex(EsConstant.ES7, indexName);
        }
        esService.createIndex(EsConstant.ES7, indexName);
        boolean b = esService.existIndex(EsConstant.ES7, indexName);

        String indexName8 = "test_es8_index";
        if (esService.existIndex(EsConstant.ES8, indexName8)) {
            esService.deleteIndex(EsConstant.ES8, indexName8);
        }
        esService.createIndex(EsConstant.ES8, indexName8);
        boolean b8 = esService.existIndex(EsConstant.ES8, indexName8);
        return ResBody.builder().build().ok();
    }

    @Operation(summary = "测试es7")
    @GetMapping(TEST_ES7)
    public ResBody testEs7() throws Exception {
        String indexName = "test_es7_index";
        es7Service.deleteIndex(EsConstant.ES1, indexName);
        es7Service.createIndex(EsConstant.ES1, indexName);
        boolean b = es7Service.existIndex(EsConstant.ES1, indexName);
        return ResBody.builder().build().ok();
    }

    @Operation(summary = "复杂查询")
    @GetMapping(TEST_MIX_QUERY)
    public ResBody testMixQuery() throws Exception {
        String indexName = "test_hzc_product";
        if (esService.existIndex(EsConstant.ES7, indexName)) {
            esService.deleteIndex(EsConstant.ES7, indexName);
        }
        esService.createIndex(EsConstant.ES7, indexName);

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        class Product {
            private String name;
            private Integer price;
            private String status;
            private String category;
            private Integer stock;
        }
        //插入数据
        esService.indexDocument(EsConstant.ES7, indexName, "1", new Product("手机",2000,"ss","电子产品",1));
        esService.indexDocument(EsConstant.ES7, indexName, "2", new Product("手机",500,"aa","电子产品",1));


        // 构建各种查询条件
        Query nameQuery = esService.buildMatchQuery("name", "手机");
        Query priceRangeQuery = esService.buildRangeQuery("price", 1000, 5000);
        Query categoryQuery = esService.buildMatchQuery("category", "电子产品");
        Query notQuery = esService.buildMatchQuery("status", "下架");
        Query filterQuery = esService.buildRangeQuery("stock", 1, null);

        // 执行布尔查询
        List<JSONObject> products = esService.executeBoolQuery(
                EsConstant.ES7,
                indexName,
                Arrays.asList(nameQuery, priceRangeQuery), // must条件
//                new ArrayList<>(),
//                new ArrayList<>(),
//                new ArrayList<>(),
                Collections.singletonList(categoryQuery),  // should条件
                Collections.singletonList(notQuery),       // must_not条件
                Collections.singletonList(filterQuery),    // filter条件
                JSONObject.class
        );

        return ResBody.builder().build().ok();
    }


    public static void main(String[] args) {
        // 创建 RestHighLevelClient 实例
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("172.16.242.19", 9200, "http")));
        // 定义索引请求
        CreateIndexRequest request = new CreateIndexRequest("example_index");
        // 通过 JSON 字符串方式定义索引结构
        String mapping = """
                {
                     "properties": {
                         "createTime": {
                             "type": "date",
                             "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                         },
                         "mac": {
                             "type": "text"
                         }
                     }
                }
                """;
        // 设置映射到索引请求中
        request.source(mapping, XContentType.JSON);
        try {
            // 执行创建索引请求
            CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
            // 获取响应并打印是否成功创建索引
            boolean acknowledged = createIndexResponse.isAcknowledged();
            System.out.println("Index creation acknowledged: " + acknowledged);
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            // 关闭客户端连接
            try {
                client.close();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }
}
